import os
import hashlib
import pickle
import pandas as pd


class SourceDataLoader:
    """
    DataLoader class is responsible for loading data from several given files:
    1. string data from example.txt
    2. load rules data from seed_data_rules.csv into a pandas DataFrame
    """
    def __init__(self, config, common_paths):
        self.config = config
        self.common_paths = common_paths
        self.file_hash_path = os.path.join(self.common_paths.get('meta-data-path'), 'file_hash.pkl')

    def _calculate_hash(self, file_path):
        with open(file_path, 'rb') as f:
            return hashlib.sha256(f.read()).hexdigest()

    def _save_hash(self, file_hashes, file_path, file_hash):
        file_hashes.update({file_path: file_hash})
        with open(self.file_hash_path, 'wb') as f:
            pickle.dump(file_hashes, f)

    def _load_hash(self):
        try:
            with open(self.file_hash_path, 'rb') as f:
                return pickle.load(f)
        except FileNotFoundError:
            return {}

    def has_file_changed(self, file_path):
        file_hash = self._calculate_hash(file_path)
        file_hashes = self._load_hash()

        if file_path not in file_hashes or file_hashes[file_path] != file_hash:
            self._save_hash(file_hashes, file_path, file_hash)
            return True

        return False

    def load_data(self, output_dir):
        unchanged = False
        example_txt_path = os.path.join(output_dir, 'example.txt')
        rules_csv_path = os.path.join(output_dir, 'seed_data_rules.csv')
        if not self.has_file_changed(example_txt_path) and not self.has_file_changed(rules_csv_path):
            unchanged = True
        # Load string data from example.txt
        with open(example_txt_path, 'r') as file:
            example_string = file.read()
        # Load rules data from seed_data_rules.csv
        rules_df = pd.read_csv(rules_csv_path)
        
        return unchanged, example_string, rules_df
